﻿using System.Diagnostics.Contracts;
using DaveSexton.Labs;

namespace System.Diagnostics
{
	public abstract class TraceListener : IDisposable
	{
		#region Public Properties
		public virtual string Name
		{
			get
			{
				Contract.Ensures(Contract.Result<string>() != null);

				return name;
			}
			set
			{
				Contract.Requires(value != null);

				name = value;
			}
		}
		#endregion

		#region Private / Protected
		private string name;
		#endregion

		#region Constructors
		/// <summary>
		/// Constructs a new instance of the <see cref="TraceListener" /> class for derived classes.
		/// </summary>
		protected TraceListener(string name)
		{
			Contract.Requires(name != null);

			this.name = name;
		}
		#endregion

		#region Methods
		[ContractInvariantMethod]
		[System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Performance", "CA1822:MarkMembersAsStatic", Justification = "Required for code contracts.")]
		private void ObjectInvariant()
		{
			Contract.Invariant(name != null);
		}

		public abstract void Write(string message);

		public abstract void WriteLine(string message);

		public virtual void TraceEvent(TraceEventCache eventCache, string source, TraceEventType eventType, int id, string format, params object[] args)
		{
			TraceEvent(eventCache, source, eventType, id, LabTraceSource.Format(format, args));
		}

		public virtual void TraceEvent(TraceEventCache eventCache, string source, TraceEventType eventType, int id, string message)
		{
			WriteLine(message);
		}

		/// <summary>
		/// Releases all resources used by an instance of the <see cref="TraceListener" /> class.
		/// </summary>
		/// <remarks>
		/// This method calls the virtual <see cref="Dispose(bool)" /> method, passing in <strong>true</strong>, and then suppresses 
		/// finalization of the instance.
		/// </remarks>
		public void Dispose()
		{
			Dispose(true);
			GC.SuppressFinalize(this);
		}

		/// <summary>
		/// Releases the unmanaged resources used by an instance of the <see cref="TraceListener" /> class and optionally releases the managed resources.
		/// </summary>
		/// <param name="disposing"><strong>true</strong> to release both managed and unmanaged resources; <strong>false</strong> to release only unmanaged resources.</param>
		protected virtual void Dispose(bool disposing)
		{
		}
		#endregion
	}
}
